package com.example.demo.service.menu;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.mgt.RealmSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.example.demo.common.MyShiroRealm;
import com.example.demo.domain.menu.Menu;
import com.example.demo.domain.role.Role;
import com.example.demo.domain.userInfo.UserInfo;
import com.example.demo.mapper.menu.MenuMapper;
import com.example.demo.mapper.role.RoleMenuMapper;

@Service("menuService")
public class MenuServiceImpl implements MenuService {
	public static final String PREMISSION_STRING = "perms[\"{0}\"]";
	@Autowired
	private MenuMapper menuMapper;

	@Autowired
	private RoleMenuMapper roleMenuMapper;

	// 根据用户ID查询权限
	@Override
	public Set<String> selectPermsByUserId(Integer uid) {
		// TODO Auto-generated method stub
		List<String> perms = menuMapper.selectPermsByUserId(uid);
		Set<String> permsSet = new HashSet<>();
		for (String perm : perms) {
			if (perm != null) {
				permsSet.addAll(Arrays.asList(perm.trim().split(",")));
			}
		}
		return permsSet;
	}

	@Override
	public List<Menu> selectMenusByUser(UserInfo user) {
		// TODO Auto-generated method stub
		List<Menu> menus = new LinkedList<Menu>();
		// 管理员显示所有菜单信息
		if (user.isAdmin()) {
			menus = menuMapper.selectMenuNormalAll();
		} else {
			menus = menuMapper.selectMenusByUserId(user.getUid());
		}
		List<Menu> returnList = new ArrayList<Menu>();
		for (Iterator<Menu> iterator = menus.iterator(); iterator.hasNext();) {
			Menu t = (Menu) iterator.next();
			// 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
			if (t.getParentId() == 0) {
				recursionFn(menus, t);
				returnList.add(t);
			}
		}
		return getChildPerms(menus, 0);
	}

	/**
     * 根据父节点的ID获取所有子节点
     * 
     * @param list 分类表
     * @param parentId 传入的父节点ID
     * @return String
     */
	private List<Menu> getChildPerms(List<Menu> list, int parentId) {
		// TODO Auto-generated method stub
		List<Menu> returnList = new ArrayList<Menu>();
        for (Iterator<Menu> iterator = list.iterator(); iterator.hasNext();)
        {
            Menu t = (Menu) iterator.next();
            // 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getParentId() == parentId)
            {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
		return returnList;
	}

	@Override
	public List<Menu> selectMenuList(Menu menu) {
		// TODO Auto-generated method stub
		return menuMapper.selectMenuList(menu);
	}

	@Override
	public List<Menu> selectMenuAll() {
		// TODO Auto-generated method stub
		return menuMapper.selectMenuAll();
	}

	/**
	 * 根据角色ID查询菜单
	 * 
	 * @param role
	 *            角色对象
	 * @return 菜单列表
	 */
	@Override
	public List<Map<String, Object>> roleMenuTreeData(Role role) {
		// TODO Auto-generated method stub
		Integer roleId = role.getRoleId();
		List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>();
		List<Menu> menuList = menuMapper.selectMenuAll();
		if (roleId != null) {
			List<String> roleMenuList = menuMapper.selectMenuTree(roleId);
			trees = getTrees(menuList, true, roleMenuList, true);
		}
		 else
	        {
	            trees = getTrees(menuList, false, null, true);
	        }
		return trees;
	}

	/**
	 * 对象转菜单树
	 * 
	 * @param menuList
	 *            菜单列表
	 * @param isCheck
	 *            是否需要选中
	 * @param roleMenuList
	 *            角色已存在菜单列表
	 * @param permsFlag
	 *            是否需要显示权限标识
	 * @return
	 */
	private List<Map<String, Object>> getTrees(List<Menu> menuList, boolean isCheck, List<String> roleMenuList,
            boolean permsFlag) {
		// TODO Auto-generated method stub
		List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>();
        for (Menu menu : menuList)
        {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id", menu.getMenuId());
            map.put("pId", menu.getParentId());
            map.put("name", transMenuName(menu, roleMenuList, permsFlag));
            map.put("title", menu.getMenuName());
            if (isCheck)
            {
                map.put("checked", roleMenuList.contains(menu.getMenuId() + menu.getPerms()));
            }
            else
            {
                map.put("checked", false);
            }
            trees.add(map);
        }
        return trees;
	}

	private Object transMenuName(Menu menu, List<String> roleMenuList, boolean permsFlag) {
		// TODO Auto-generated method stub
		StringBuffer sb = new StringBuffer();
        sb.append(menu.getMenuName());
        if (permsFlag)
        {
            sb.append("<font color=\"#888\">&nbsp;&nbsp;&nbsp;" + menu.getPerms() + "</font>");
        }
        return sb.toString();
	}

	@Override
	public List<Map<String, Object>> menuTreeData() {
		// TODO Auto-generated method stub
		List<Map<String, Object>> trees = new ArrayList<Map<String, Object>>();
        List<Menu> menuList = menuMapper.selectMenuAll();
        trees = getTrees(menuList, false, null, false); 
        return trees;
	}

	@Override
	public Map<String, String> selectPermsAll() {
		// TODO Auto-generated method stub
		LinkedHashMap<String, String> section = new LinkedHashMap<>();
		List<Menu> permissions = menuMapper.selectMenuAll();
		if (permissions != null) {
			for (Menu menu : permissions) {
				section.put(menu.getUrl(), MessageFormat.format(PREMISSION_STRING, menu.getPerms()));
			}
		}
		return section;
	}

	@Override
	public int insertMenu(Menu menu) {
		// TODO Auto-generated method stub
		RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
		MyShiroRealm realm = (MyShiroRealm) rsm.getRealms().iterator().next();
		realm.clearCachedAuthorizationInfo();
		return menuMapper.insertSelective(menu);
	}

	@Override
	public int updateMenu(Menu menu) {
		// TODO Auto-generated method stub
		RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
		MyShiroRealm realm = (MyShiroRealm) rsm.getRealms().iterator().next();
		realm.clearCachedAuthorizationInfo();
		return menuMapper.updateByPrimaryKeySelective(menu);
	}

	// 检查菜单名称唯一
	@Override
	public String checkMenuNameUnique(Menu menu) {
		// TODO Auto-generated method stub
		Integer menuId = menu.getMenuId() == null ? -1 : menu.getMenuId();
		// 检查名称以及对应的父菜单是否一致，如果一致，则重复
		Menu m = menuMapper.checkMenuNameUnique(menu.getMenuName(), menu.getParentId());
		if (m != null && menu.getMenuId() != menuId)
			return "1";
		return "0";
	}

	@Override
	public int deleteMenuById(Integer menuId) {
		// TODO Auto-generated method stub
		RealmSecurityManager rsm = (RealmSecurityManager) SecurityUtils.getSecurityManager();
		MyShiroRealm realm = (MyShiroRealm) rsm.getRealms().iterator().next();
		realm.clearCachedAuthorizationInfo();
		return menuMapper.deleteByPrimaryKey(menuId);
	}
    
	@Override
	public Menu selectMenuById(Integer menuId) {
		// TODO Auto-generated method stub
		return menuMapper.selectMenuById(menuId);
	}
	//查询子菜单数量
	@Override
	public int selectCountMenuByParentId(Integer parentId) {
		// TODO Auto-generated method stub
		return menuMapper.selectCountMenuByParentId(parentId);
	}
   //查询菜单使用数量
	@Override
	public int selectCountRoleMenuByMenuId(Integer menuId) {
		// TODO Auto-generated method stub
		return roleMenuMapper.selectCountRoleMenuByMenuId(menuId);
	}
  ///递归方法
	private static void recursionFn(List<Menu> list, Menu t) {
		// 得到子节点列表
		List<Menu> childList = getChildList(list, t);
		t.setChildren(childList);
		for (Menu tChild : childList) {
			if (hasChild(list, tChild)) {
				// 判断是否有子节点
				Iterator<Menu> it = childList.iterator();
				while (it.hasNext()) {
					Menu n = (Menu) it.next();
					recursionFn(list, n);
				}
			}
		}
	}

	/**
	 * 得到子节点列表
	 */
	private static List<Menu> getChildList(List<Menu> list, Menu t) {

		List<Menu> tlist = new ArrayList<Menu>();
		Iterator<Menu> it = list.iterator();
		while (it.hasNext()) {
			Menu n = (Menu) it.next();
			if (n.getParentId().longValue() == t.getMenuId().longValue()) {
				tlist.add(n);
			}
		}
		return tlist;
	}

	/**
	 * 判断是否有子节点
	 */
	private static boolean hasChild(List<Menu> list, Menu t) {
		return getChildList(list, t).size() > 0 ? true : false;
	}

}
